package com.huawei.zyb.taskManager.application.project;

import com.huawei.zyb.taskManager.application.project.dto.ProjectDTO;
import com.huawei.zyb.taskManager.domain.developer.repository.DeveloperRepository;
import com.huawei.zyb.taskManager.domain.developer.valueobject.DeveloperId;
import com.huawei.zyb.taskManager.domain.project.entity.Project;
import com.huawei.zyb.taskManager.domain.project.repository.ProjectRepository;
import com.huawei.zyb.taskManager.domain.project.valueobject.*;
import com.huawei.zyb.taskManager.domain.shared.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 项目应用服务
 */
@Service
@Transactional
public class ProjectApplicationService {
    
    private final ProjectRepository projectRepository;
    private final DeveloperRepository developerRepository;
    
    @Autowired
    public ProjectApplicationService(ProjectRepository projectRepository,
                                   DeveloperRepository developerRepository) {
        this.projectRepository = projectRepository;
        this.developerRepository = developerRepository;
    }
    
    /**
     * 创建项目
     */
    public ProjectDTO createProject(String name, String description, String managerId) {
        ProjectId projectId = ProjectId.of(System.currentTimeMillis());
        DeveloperId developerManagerId = null;
        if (managerId != null && !managerId.trim().isEmpty()) {
            developerManagerId = DeveloperId.of(managerId);
        }
        
        Project project = Project.create(
            projectId,
            ProjectName.of(name),
            ProjectDescription.of(description),
            developerManagerId
        );
        
        projectRepository.save(project);
        return convertToDTO(project);
    }
    
    /**
     * 分配项目经理
     */
    public void assignManager(Long projectId, String managerId) {
        Project project = getProjectById(projectId);
        
        // 验证开发者是否存在且有管理权限
        if (!developerRepository.existsById(DeveloperId.of(managerId))) {
            throw new BusinessException("开发者不存在");
        }
        
        // 简化权限检查，假设所有开发者都有管理权限
        
        project.assignManager(DeveloperId.of(managerId));
        projectRepository.save(project);
    }
    
    /**
     * 开始项目
     */
    public void startProject(Long projectId) {
        Project project = getProjectById(projectId);
        project.start();
        projectRepository.save(project);
    }
    
    /**
     * 暂停项目
     */
    public void pauseProject(Long projectId) {
        Project project = getProjectById(projectId);
        project.updateStatus(ProjectStatus.CANCELLED);
        projectRepository.save(project);
    }
    
    /**
     * 恢复项目
     */
    public void resumeProject(Long projectId) {
        Project project = getProjectById(projectId);
        project.resume();
        projectRepository.save(project);
    }
    
    /**
     * 完成项目
     */
    public void completeProject(Long projectId) {
        Project project = getProjectById(projectId);
        project.complete();
        projectRepository.save(project);
    }
    
    /**
     * 取消项目
     */
    public void cancelProject(Long projectId) {
        Project project = getProjectById(projectId);
        project.cancel();
        projectRepository.save(project);
    }
    
    /**
     * 更新项目信息
     */
    public void updateProject(Long projectId, String name, String description) {
        Project project = getProjectById(projectId);
        project.updateInfo(ProjectName.of(name), ProjectDescription.of(description));
        projectRepository.save(project);
    }
    
    /**
     * 删除项目
     */
    public void deleteProject(Long projectId) {
        Project project = getProjectById(projectId);
        
        if (projectRepository.hasIncompleteRequirements(project.getId())) {
            throw new BusinessException("项目有未完成的需求，不能删除");
        }
        
        projectRepository.deleteById(project.getId());
    }
    
    /**
     * 根据ID查找项目
     */
    @Transactional(readOnly = true)
    public ProjectDTO findById(Long projectId) {
        Project project = getProjectById(projectId);
        return convertToDTO(project);
    }
    
    /**
     * 根据项目经理ID查找项目列表
     */
    @Transactional(readOnly = true)
    public List<ProjectDTO> findByManagerId(String managerId) {
        List<Project> projects = projectRepository.findByManagerId(managerId);
        return projects.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    /**
     * 根据状态查找项目列表
     */
    @Transactional(readOnly = true)
    public List<ProjectDTO> findByStatus(ProjectStatus status) {
        List<Project> projects = projectRepository.findByStatus(status);
        return projects.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    /**
     * 查找所有项目
     */
    @Transactional(readOnly = true)
    public List<ProjectDTO> findAll() {
        List<Project> projects = projectRepository.findAll();
        return projects.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    /**
     * 根据名称模糊查询项目
     */
    @Transactional(readOnly = true)
    public List<ProjectDTO> findByNameLike(String name) {
        List<Project> projects = projectRepository.findAll().stream()
                .filter(project -> project.getName().getValue().contains(name))
                .collect(Collectors.toList());
        return projects.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    

    

    
    /**
     * 统计项目数量
     */
    @Transactional(readOnly = true)
    public long countProjects() {
        return projectRepository.findAll().size();
    }
    
    /**
     * 统计项目经理项目数量
     */
    @Transactional(readOnly = true)
    public long countByManagerId(String managerId) {
        return projectRepository.findByManagerId(managerId).size();
    }
    
    private Project getProjectById(Long projectId) {
        return projectRepository.findById(ProjectId.of(projectId))
                .orElseThrow(() -> new BusinessException("项目不存在"));
    }
    
    private ProjectDTO convertToDTO(Project project) {
        return new ProjectDTO(
            project.getId().getValue(),
            project.getName().getValue(),
            project.getDescription().getValue(),
            project.getStatus(),
            project.getManagerId() != null ? project.getManagerId().getValue() : null,
            project.getCreatedAt(),
            project.getUpdatedAt()
        );
    }
}